"""
企业级金融数据MCP服务系统 - 基础数据模型
提供所有金融数据模型的基础类和混入类
"""

from datetime import datetime, timezone
from typing import Optional, Dict, Any
from sqlalchemy import String, DateTime, Boolean, Integer, Text, JSON
from sqlalchemy.orm import Mapped, mapped_column, declarative_mixin
from sqlalchemy.dialects.postgresql import JSONB, UUID
import uuid

from ..core.database import BaseModel


class BaseFinancialModel(BaseModel):
    """
    金融数据基础模型类
    继承自BaseModel，添加金融数据特有的字段和方法
    """
    __abstract__ = True
    
    # 数据源标识
    data_source: Mapped[str] = mapped_column(String(50), nullable=False, default="akshare", comment="数据源")
    
    # 数据质量评分 (0-100)
    data_quality_score: Mapped[Optional[int]] = mapped_column(Integer, nullable=True, comment="数据质量评分")
    
    # 数据状态：raw(原始), processed(已处理), validated(已验证), archived(已归档)
    data_status: Mapped[str] = mapped_column(String(20), nullable=False, default="raw", comment="数据状态")
    
    # 扩展元数据
    metadata_: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True, comment="扩展元数据")
    
    def __repr__(self) -> str:
        return f"<{self.__class__.__name__}(id={self.id}, data_source={self.data_source})>"


@declarative_mixin
class DataVersionMixin:
    """
    数据版本控制混入类
    为需要版本控制的数据模型提供版本管理功能
    """
    
    # 数据版本号
    version: Mapped[int] = mapped_column(Integer, nullable=False, default=1, comment="数据版本号")
    
    # 版本创建时间
    version_created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), 
        nullable=False, 
        default=lambda: datetime.now(timezone.utc),
        comment="版本创建时间"
    )
    
    # 版本创建者
    version_created_by: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="版本创建者")
    
    # 版本变更说明
    version_notes: Mapped[Optional[str]] = mapped_column(Text, nullable=True, comment="版本变更说明")
    
    # 是否为当前版本
    is_current_version: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, comment="是否为当前版本")
    
    # 父版本ID（用于版本链追踪）
    parent_version_id: Mapped[Optional[str]] = mapped_column(
        UUID(as_uuid=False), 
        nullable=True, 
        comment="父版本ID"
    )


@declarative_mixin  
class SyncStatusMixin:
    """
    数据同步状态混入类
    为需要同步状态跟踪的数据模型提供同步管理功能
    """
    
    # 最后同步时间
    last_sync_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), 
        nullable=True,
        comment="最后同步时间"
    )
    
    # 同步状态：pending(待同步), syncing(同步中), synced(已同步), failed(同步失败)
    sync_status: Mapped[str] = mapped_column(
        String(20), 
        nullable=False, 
        default="pending",
        comment="同步状态"
    )
    
    # 同步错误信息
    sync_error: Mapped[Optional[str]] = mapped_column(Text, nullable=True, comment="同步错误信息")
    
    # 同步重试次数
    sync_retry_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0, comment="同步重试次数")
    
    # 下次同步时间
    next_sync_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), 
        nullable=True,
        comment="下次同步时间"
    )
    
    # 同步配置
    sync_config: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True, comment="同步配置")


@declarative_mixin
class AuditMixin:
    """
    审计日志混入类
    为需要审计跟踪的数据模型提供审计功能
    """
    
    # 创建者
    created_by: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="创建者")
    
    # 最后修改者
    updated_by: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="最后修改者")
    
    # 审计日志
    audit_log: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True, comment="审计日志")
    
    # IP地址
    client_ip: Mapped[Optional[str]] = mapped_column(String(45), nullable=True, comment="客户端IP地址")
    
    # 用户代理
    user_agent: Mapped[Optional[str]] = mapped_column(Text, nullable=True, comment="用户代理")


@declarative_mixin
class PartitionMixin:
    """
    分区混入类
    为需要分区的数据模型提供分区键支持
    """
    
    # 分区日期（用于时间分区）
    partition_date: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), 
        nullable=True,
        comment="分区日期"
    )
    
    # 分区键（用于自定义分区）
    partition_key: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="分区键")


class DataSyncTask(BaseFinancialModel):
    """
    数据同步任务模型
    用于管理和跟踪数据同步任务的执行状态
    """
    __tablename__ = "data_sync_tasks"
    
    # 任务名称
    task_name: Mapped[str] = mapped_column(String(200), nullable=False, comment="任务名称")
    
    # 任务类型
    task_type: Mapped[str] = mapped_column(String(50), nullable=False, comment="任务类型")
    
    # 目标表名
    target_table: Mapped[str] = mapped_column(String(100), nullable=False, comment="目标表名")
    
    # API函数名
    api_function: Mapped[str] = mapped_column(String(100), nullable=False, comment="API函数名")
    
    # API参数
    api_params: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True, comment="API参数")
    
    # 任务状态：pending(待执行), running(执行中), completed(已完成), failed(失败), cancelled(已取消)
    task_status: Mapped[str] = mapped_column(String(20), nullable=False, default="pending", comment="任务状态")
    
    # 开始时间
    started_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True, comment="开始时间")
    
    # 完成时间
    completed_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True, comment="完成时间")
    
    # 处理记录数
    processed_records: Mapped[int] = mapped_column(Integer, nullable=False, default=0, comment="处理记录数")
    
    # 成功记录数
    success_records: Mapped[int] = mapped_column(Integer, nullable=False, default=0, comment="成功记录数")
    
    # 失败记录数
    failed_records: Mapped[int] = mapped_column(Integer, nullable=False, default=0, comment="失败记录数")
    
    # 错误信息
    error_message: Mapped[Optional[str]] = mapped_column(Text, nullable=True, comment="错误信息")
    
    # 执行日志
    execution_log: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True, comment="执行日志")
    
    # 调度配置
    schedule_config: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB, nullable=True, comment="调度配置")
    
    def __repr__(self) -> str:
        return f"<DataSyncTask(id={self.id}, task_name={self.task_name}, status={self.task_status})>"


class DataValidationRule(BaseFinancialModel):
    """
    数据验证规则模型
    定义各类金融数据的验证规则和质量检查标准
    """
    __tablename__ = "data_validation_rules"
    
    # 规则名称
    rule_name: Mapped[str] = mapped_column(String(200), nullable=False, comment="规则名称")
    
    # 规则类型：range(范围检查), format(格式检查), logic(逻辑检查), reference(引用检查)
    rule_type: Mapped[str] = mapped_column(String(50), nullable=False, comment="规则类型")
    
    # 目标表名
    target_table: Mapped[str] = mapped_column(String(100), nullable=False, comment="目标表名")
    
    # 目标字段
    target_field: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="目标字段")
    
    # 规则配置
    rule_config: Mapped[Dict[str, Any]] = mapped_column(JSONB, nullable=False, comment="规则配置")
    
    # 错误级别：warning(警告), error(错误), critical(严重)
    error_level: Mapped[str] = mapped_column(String(20), nullable=False, default="error", comment="错误级别")
    
    # 是否启用
    is_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, comment="是否启用")
    
    # 规则描述
    description: Mapped[Optional[str]] = mapped_column(Text, nullable=True, comment="规则描述")
    
    def __repr__(self) -> str:
        return f"<DataValidationRule(id={self.id}, rule_name={self.rule_name}, target_table={self.target_table})>"